# utils.py
import pyautogui
import time
import cv2
import numpy as np
from settings import base_y, button_coords, search_regions, search_regions_size, is_resize, sleep_options
import logging
from logging.handlers import TimedRotatingFileHandler
import os
import datetime

# 定义一个全局变量 stop_event，但不初始化
stop_event = None

# 全局配置日志记录，避免重复添加处理器
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

# 创建日志目录
log_dir = 'logs/tem'
if not os.path.exists(log_dir):
    os.makedirs(log_dir)

# 获取当前日期
current_date = datetime.datetime.now().strftime("%Y-%m-%d")
# 配置日志记录
log_file = os.path.join(log_dir, f'qingyun_{current_date}.log')
formatter = logging.Formatter('[%(asctime)s] - %(message)s', '%Y-%m-%d %H:%M:%S')

# 配置文件处理器
file_handler = TimedRotatingFileHandler(log_file, when='D', interval=1)
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)

# 配置控制台处理器
console_handler = logging.StreamHandler()
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)

def set_stop_event(event):
    global stop_event
    stop_event = event

def move_and_click(button_name_or_coords, delay=sleep_options["默认移动点击"]):
    """
    该函数用于根据按钮名称从坐标字典中获取坐标，
    或者直接使用传入的坐标，将鼠标移动到指定坐标并进行点击操作，
    同时可设置操作前的延迟时间。
    :param button_name_or_coords: 按钮名称或坐标元组 (x, y)
    :param delay: 操作前的延迟时间，默认为 0.8 秒
    """
    if stop_event and stop_event.is_set():
        return
    if isinstance(button_name_or_coords, str):
        if button_name_or_coords in button_coords:
            x, offset_y = button_coords[button_name_or_coords]
            # 计算实际的 y 坐标
            y = base_y - offset_y
        else:
            print(f"未找到 {button_name_or_coords} 的坐标信息。")
            return
    elif isinstance(button_name_or_coords, tuple) and len(button_name_or_coords) == 2:
        x, y = button_name_or_coords
    else:
        print(f"传入的参数 {button_name_or_coords} 格式不正确。")
        return

    time.sleep(delay)
    if stop_event and stop_event.is_set():
        return
    pyautogui.moveTo(x, y)
    pyautogui.click()


def capture_screenshot(region_name="default", delay=sleep_options["默认截图"]):
    """
    根据指定的区域名称进行截图并返回截取的图片。
    :param region_name: 搜索区域的名称，从 search_regions 字典中获取
    :return: 截取的图片（OpenCV 格式的图像），若出现问题则返回 None
    """
    if stop_event and stop_event.is_set():
        return None

    if region_name in search_regions:
        region = search_regions[region_name]
        if region is not None:
            left, top, width, height = region
            search_region = (left, base_y - top, width, height)
        else:
            search_region = None  # 搜索全屏幕范围
    else:
        print(f"未找到 {region_name} 的搜索区域信息。")
        return None

    try:
        time.sleep(delay)
        # 进行截图
        if search_region:
            screenshot = pyautogui.screenshot(region=search_region)
        else:
            screenshot = pyautogui.screenshot()

        # 将 PIL 图像转换为 OpenCV 格式
        screenshot = np.array(screenshot)
        screenshot = cv2.cvtColor(screenshot, cv2.COLOR_RGB2BGR)
        # 不同分辨率的截图需要重新调整大小
        if is_resize:
            size = search_regions_size[region_name]
            screenshot = cv2.resize(screenshot, size)
#         save_path = f"images/seal/base.png"
#         cv2.imwrite(save_path, screenshot)
#         print(f"保存截图")
        return screenshot
    except Exception as e:
        print(f"截图时出现错误: {e}")
        return None

def check_color(button_name, target_color, delay=0):
    """
    检查指定按钮的颜色
    """
    time.sleep(delay)
    x, y = button_coords[button_name]
    screenshot = pyautogui.screenshot(region=(x, base_y - y, 1, 1))
    # 将截图转换为 numpy 数组
    image = np.array(screenshot)
    r, g, b = image[0, 0][:3]
#     print(f"坐标 ({x}, {y}) 的颜色: RGB({r}, {g}, {b})")
    target_r, target_g, target_b = target_color
    diff_r = abs(r - target_r)
    diff_g = abs(g - target_g)
    diff_b = abs(b - target_b)
    error_margin = 30
    return diff_r < error_margin and diff_g < error_margin and diff_b < error_margin

def move_relative(x_offset, y_offset, delay=0):
    """
    封装 pyautogui.moveRel 方法，可设置延迟时间并检查是否停止
    :param x_offset: x 轴偏移量
    :param y_offset: y 轴偏移量
    :param delay: 操作前的延迟时间，默认为 0 秒
    """
    if stop_event and stop_event.is_set():
        return
    time.sleep(delay)
    pyautogui.moveRel(x_offset, y_offset)

def save_log(content):
    """
    打印内容，并将内容按天保存到日志文件，同时在控制台打印日志，日志文件存放在 logs 子目录中
    :param content: 需要打印的内容
    """
    logger.info(content)

def press_key(keys, wait_time=2, is_combination=False):
    """
    模拟按下指定的键
    :param keys: 要按下的键，可以是单个键的字符串，也可以是多个键的列表
    :param wait_time: 按下键之前的等待时间，单位为秒，默认为 2 秒
    :param is_combination: 是否为组合键，即多个键同时按下，默认为 False
    """
    # 等待指定的时间，方便切换到需要操作的窗口
    time.sleep(wait_time)

    if isinstance(keys, str):
        # 如果传入的是单个键，直接按下
        pyautogui.press(keys)
    elif isinstance(keys, list):
        if is_combination:
            # 如果是组合键，使用 hotkey 函数同时按下多个键
            pyautogui.hotkey(*keys)
        else:
            # 如果不是组合键，依次按下多个键
            for key in keys:
                pyautogui.press(key)

# 测试代码
if __name__ == "__main__":
    time.sleep(2)
    check_color("刷新商品")
